/*
 * Couleur.cpp
 *
 *  Created on: 5 déc. 2009
 *      Author: math
 */

#include <math.h>
#include <iostream>
#include "liblut/core/LutColor.h"

/*---------------------------------------------------------------------------*/
/*                  Constructeur par défaut                                  */
/*           couleur: composantes par défaut: 0,0,0,0                        */
/*---------------------------------------------------------------------------*/
LutColor::LutColor() :
        m_C1(0), m_C2(0), m_C3(0), m_colorSpace(rgb_cs)
{}


LutColor::LutColor(const LutColor& color):
     m_C1(color.getC1() ), m_C2(color.getC2()), m_C3(color.getC3()),
     m_colorSpace(color.getColorSpace())
{}

/*---------------------------------------------------------------------------*/
/*    Définition d'une couleur à partir des valeurs de ses composantes       */
/*    (valeurs données en entrée)                                            */
/*---------------------------------------------------------------------------*/
LutColor::LutColor(int V1, int V2, int V3, eLutColorSpace Type) :
    m_C1(V1), m_C2(V2), m_C3(V3), m_colorSpace(Type)
{
  if(m_colorSpace == rgb_cs)
    {
      if(m_C1 < 0 ) {m_C1 =0;}
      if(m_C2 < 0 ) {m_C2 =0;}
      if(m_C3 < 0 ) {m_C3 =0;}
      if(m_C1 > 255 ) {m_C1 =255;}
      if(m_C2 > 255 ) {m_C2 =255;}
      if(m_C3 > 255 ) {m_C3 =255;}
    }
  if(m_colorSpace == hsl_cs)
    {
      if(m_C1 < 0 ) {m_C1 =0;}
      if(m_C2 < 0 ) {m_C2 =0;}
      if(m_C3 < 0 ) {m_C3 =0;}
      if(m_C1 > 360 ) {m_C1 =360;}
      if(m_C2 > 255 ) {m_C2 =255;}
      if(m_C3 > 255 ) {m_C3 =255;}
    }
}

/*---------------------------------------------------------------------------*/
/*    Redéfinition d'une couleur à partir des valeurs de ses composantes     */
/*                     (valeurs données en entrée)                           */
/*---------------------------------------------------------------------------*/
void LutColor::setValues(int V1, int V2, int V3){
    //permet de définir une couleur Ã  partir de ses composantes
    //et du système de couleur dans lequel elle est définie
   m_C1=V1;
   m_C2=V2;
   m_C3=V3;
   if(m_colorSpace == rgb_cs)
     {
       if(m_C1 < 0 ) {m_C1 =0;}
       if(m_C2 < 0 ) {m_C2 =0;}
       if(m_C3 < 0 ) {m_C3 =0;}
       if(m_C1 > 255 ) {m_C1 =255;}
       if(m_C2 > 255 ) {m_C2 =255;}
       if(m_C3 > 255 ) {m_C3 =255;}
     }
   if(m_colorSpace == hsl_cs)
     {
       if(m_C1 < 0 ) {m_C1 =0;}
       if(m_C2 < 0 ) {m_C2 =0;}
       if(m_C3 < 0 ) {m_C3 =0;}
       if(m_C1 > 360 ) {m_C1 =360;}
       if(m_C2 > 255 ) {m_C2 =255;}
       if(m_C3 > 255 ) {m_C3 =255;}
     }
}

/*void LutColor::SetColorSpace(int systColor)
{
     m_systCouleur=systColor;
}*/

//         on a une couleur en TSL et on la converti en RVB
/*--------------------------------------------------------------------------*/
/*  Conversion d'une couleur en TSL en une couleur en RVB                   */
/*  from TSL ( 360,255,255) to RVB (255,255,255)                            */
/*--------------------------------------------------------------------------*/
void LutColor::HSL2RGB(int& C1, int& C2, int& C3){
    //std::cout<<"HSL in "<<C1<<" "<<C2<<" "<<C3<<std::endl;
    int R,V,B;
    //on est en TSL donc C1=teinte, C2=saturation, C3=luminance
    //calcul de la transformation de TSL vers RVB
    double T=(double) C1/360;
    double S= (double) C2/255;
    double L=(double) C3/255;
    double v;
    if(L<=0.5){
       v=L*(1+S);
    }
    else{
       v=L+S-L*S;
    }
    double teinte=T*6.0;
    int i=(int) teinte;
    double fract= teinte-i;
    double m=2*L-v;
    double sv= (v-m)/v;
    double vsf=v*sv*fract;
    double mid1=m+vsf;
    double mid2=v-vsf;
    double R1,V1,B1;
    switch(i){
      case 0:
          R1=v;
          V1=mid1;
          B1=m;
          break;
      case 1:
          R1=mid2;
          V1=v;
          B1=m;
          break;
      case 2:
          R1=m;
          V1=v;
          B1=mid1;
          break;
      case 3:
          R1=m;
          V1=mid2;
          B1=v;
          break;
      case 4:
          R1=mid1;
          V1=m;
          B1=v;
          break;
      case 5:
           R1=v;
           V1=m;
           B1=mid2;
           break;
    }
    //on travaille uniquement dans des couleurs définie par des entiers
    R=(int)(R1*255);
    V= (int)(V1*255);
    B= (int)(B1*255);
    //les couleurs doivent de situer dans l'intervalle [0;255]
    if(R<0) { R = 0; }
    if(V<0) { V = 0; }
    if(B<0) { B = 0; }
    if(R>255){ R = 255;}
    if(V>255){ V = 255;}
    if(B>255){ B = 255;}
    C1 = R;
    C2 = V;
    C3 = B;
    //std::cout<<"RVB out "<<C1<<" "<<C2<<" "<<C3<<std::endl;
}

LutColor
LutColor::toRGB()
 {
    LutColor rgb_color(0,0,0,rgb_cs);
    if(m_colorSpace == rgb_cs){
        rgb_color.setValues(m_C1,m_C2,m_C3);
    }
    if(m_colorSpace == hsl_cs){
        int C1 = m_C1;
        int C2 = m_C2;
        int C3 = m_C3;
        HSL2RGB(C1,C2,C3);
        rgb_color.setValues(C1,C2,C3);
     }
    return rgb_color;
 }

LutColor::~LutColor() {
	// TODO Auto-generated destructor stub
}
